// Operating Systems, Spring 2012.

/**
   The PrimaryStore interface defines the simulator methods and classes
   available to an operating system.

   The PrimaryStore interface does not have to be implemented as part of an
   operating system.  The PrimaryStore interface been already been implemented
   as part of the simulator, and does not require further implementation.
 */


interface 
PrimaryStore {

  /**
     Fetch a value from store.

     @param addr The address from which the value should be fetched.

     @returns The value fetched from addr.  Panic if addr is not valid.
   */

  int fetch(int addr);


  /**
     Find a page-table entry.

     @param index The index of the page-table entry of interest.

     @returns A reference to the page-table entry associated with the given
     index.  Panic if the given index isn't valid.
  */

  PageTableEntry pageTableEntry(int index);


  /** 
      Find a page-table entry's index.

      @param pte A reference to a page-table entry of interest.

      @returns The index of the given page-table entry.  Panic if the given
      page-table entry isn't valid.
  */

  int pageTableEntryIndex(PageTableEntry pte);


  /**
     Store a value.  Panic if the given address isn't valid.

     @param addr The address at which the value will be stored.

     @param word The value to store.
   */

  void store(int addr, int word);


  /**
     Translate a virtual address to a physical address

     @param pid The id of the process issuing the virtual address.

     @param va The virtual address to translate.

     @param write True iff va is the target of a write.

     @returns The result of the transation.
  */

  TranslationResult va2pa(int pid, int va, boolean write);


  /**
     Find the page number associated with a virtual address.

     @param va The virtual address of interest.

     @return The page number associated with the given virtual address.  Panic
     if va isn't a valid virtual address.
   */

  int virtualAddressPageNumber(int va);


  /** 
      Each page frame in user space is associated with an entry in the page
      table.  The hardware maintains only the accessedAt and modifiedAt fields;
      all other fields must be maintained by the paging code in the operating
      system.
  */

  class
  PageTableEntry {

    /**
       The most recent clock tick on which the page associated with this page
       table entry was accessed.  This field is maintained by the hardware on
       each access to the page; an os may also change this value.
    */

    int accessedAt;


    /**
       The most recent clock tick on which the page associated with this page
       table entry was modified.  This field is maintained by the hardware on
       each access to the page; an os may also change this value.
    */

    int modifiedAt;


    /**
       The page number (the left-most six bits) for the range of virtual
       addresses contained in the associated page.
    */

    int pageNumber;


    /**
       The id of the process from which the page associated with this page
       table entry came.
    */

    int processID;


    /** 
	If valid is true, this page table entry contains valid information;
	otherwise the information in this entry is garbage.
    */

    boolean valid;


    /**
       Get a string representation of this page-table entry.

       @returns A string representation of this page-table entry.
     */

    @Override
    public String
    toString() {
      if (valid)
        return String.format(
          "process-id: %d, accessed-at: %d, modified-at: %d, page-number: %d",
	  processID, accessedAt, modifiedAt, pageNumber);
      else
	return "valid: false";
      }
    }


  /**
     The result of translating a virtual address to a physical address.
   */

  class TranslationResult {

    /** 
	True iff the virtual-address translation succeeded.
    */

    final boolean valid;


    /**
       If valid is true, physicalAddress contains the physical address
       corresponding to a virtual address.  If valid is false, physicalAddress
       contains an undefined value.
     */

    final int physicalAddress;


    /**
       Create a translation result.

       @param v Indicates if the translation is valid.

       @param pa The physical address resulting from a valid virtual-address
       translation.
     */

    TranslationResult(boolean v, int pa) {
      valid = v;
      physicalAddress = pa;
      }
    }
  }


// $Log: PrimaryStore.java,v $
// Revision 1.1  2012/02/12 20:37:03  rclayton
// Initial revision
//